using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Input;
using System;

partial class Player : AnimatedGameObject
{
    protected Vector2 startPosition;
    protected bool isOnTheGround;
    protected float previousYPosition;
    protected bool isAlive;
    protected bool exploded;
    protected bool finished;
    protected bool walkingOnIce, walkingOnHot;
    protected bool walkingRight, walkingLeft;
    protected bool doubleJumped;
    protected bool bombActive;
    float cameraFriction = 10;
    //Costs to do actions in seconds
    int doublejumpCosts = 5;
    int bombCosts = 3;
    protected AnimatedGameObject doubleJumpAnimation;

    public Player(Vector2 start) : base(2, "player")
    {
        this.LoadAnimation("Sprites/Player/spr_idle", "idle", true); 
        this.LoadAnimation("Sprites/Player/spr_run@13", "run", true, 0.05f);
        this.LoadAnimation("Sprites/Player/spr_jump@14", "jump", false, 0.05f); 
        this.LoadAnimation("Sprites/Player/spr_celebrate@14", "celebrate", false, 0.05f);
        this.LoadAnimation("Sprites/Player/spr_die@5", "die", false);
        this.LoadAnimation("Sprites/Player/spr_explode@5x5", "explode", false, 0.04f);

        doubleJumpAnimation = new AnimatedGameObject();
        doubleJumpAnimation.LoadAnimation("Sprites/Player/spr_explode@5x5", "explode", false, 0.04f);

        startPosition = start;
        Reset();
    }

    public override void Draw(GameTime gameTime, Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
    {
        base.Draw(gameTime, spriteBatch);

        doubleJumpAnimation.Draw(gameTime, spriteBatch);
    }

    public override void Reset()
    {
        this.position = startPosition;
        this.velocity = Vector2.Zero;
        isOnTheGround = true;
        isAlive = true;
        exploded = false;
        finished = false;
        walkingOnIce = false;
        walkingOnHot = false;
        this.PlayAnimation("idle");
        previousYPosition = BoundingBox.Bottom;
    }

    public override void HandleInput(InputHelper inputHelper)
    {
        if (!isAlive)
            return;
        if (inputHelper.IsKeyDown(Keys.Left) && isOnTheGround)
            walkingLeft = true;
        else
            walkingLeft = false;
        if (inputHelper.IsKeyDown(Keys.Right) && isOnTheGround)
            walkingRight = true;
        else
            walkingRight = false;
        if (velocity.X != 0.0f)
            Mirror = velocity.X < 0;
        if (inputHelper.KeyPressed(Keys.Up))
        {
            if (isOnTheGround)
                Jump();
            else if (!doubleJumped)
                DoubleJump();
        }
        if (inputHelper.KeyPressed(Keys.Space))
        {
            throwBomb();
        }
    }
    void throwBomb()
    {
        //Only allow 1 bomb in the level at a time.
        if (GameWorld.Find("bomb") == null)
        {
            //Create bomb
            Bomb bomb = new Bomb(new Vector2(position.X, position.Y - sprite.Height), velocity.X, 1, "bomb");
            (parent as Level).Add(bomb);
            bombActive = true;

            (parent as Level).Timer.TimeLeft -= TimeSpan.FromSeconds(bombCosts);
        }
    }
    public override void Update(GameTime gameTime)
    {
        base.Update(gameTime);
        if (!finished && isAlive)
        {
            if (isOnTheGround)
                if (velocity.X == 0)
                    this.PlayAnimation("idle");
                else
                    this.PlayAnimation("run");
            else if (velocity.Y < 0)
                this.PlayAnimation("jump");

            TimerGameObject timer = (parent as Level).Timer;
            if (walkingOnHot)
                timer.Multiplier = 2;
            else if (walkingOnIce)
                timer.Multiplier = 0.5;
            else
                timer.Multiplier = 1;

            TileField tiles = GameWorld.Find("tiles") as TileField;
            if (BoundingBox.Top >= tiles.Rows * tiles.CellHeight)
                this.Die(true);
        }

        DoPhysics();

        //Move camera
        Vector2 newpos = position - new Vector2(0, Height) / 2f;

        //limit camera movement to the level.
        if (newpos.X < GameEnvironment.Screen.X / 2)
            newpos.X = GameEnvironment.Screen.X / 2;
        else if (newpos.X > (parent as Level).Width - GameEnvironment.Screen.X / 2)
            newpos.X = (parent as Level).Width - GameEnvironment.Screen.X / 2;

        if (newpos.Y > (parent as Level).Height - GameEnvironment.Screen.Y / 2)
            newpos.Y = (parent as Level).Height - GameEnvironment.Screen.Y / 2;
        GameEnvironment.GameCamera.CameraPosition += (newpos - GameEnvironment.GameCamera.CameraPosition) / cameraFriction;

        //Update the explosion animation for the doublejump
        doubleJumpAnimation.Update(gameTime);
    }

    public void Explode()
    {
        if (!isAlive || finished)
            return;
        isAlive = false;
        exploded = true;
        velocity = Vector2.Zero;
        position.Y += 15;
        this.PlayAnimation("explode");
    }

    public void Die(bool falling)
    {
        if (!isAlive || finished)
            return;
        isAlive = false;
        velocity.X = 0.0f;
        if (falling)
            GameEnvironment.AssetManager.PlaySound("Sounds/snd_player_fall");
        else
        {
            velocity.Y = -900;
            GameEnvironment.AssetManager.PlaySound("Sounds/snd_player_die");
        }
        this.PlayAnimation("die");
    }

    public bool IsAlive
    {
        get { return isAlive; }
    }

    public bool Finished
    {
        get { return finished; }
    }
    public bool BombActive
    {
        get { return bombActive; }
    }

    public void LevelFinished()
    {
        finished = true;
        velocity.X = 0.0f;
        this.PlayAnimation("celebrate");
        GameEnvironment.AssetManager.PlaySound("Sounds/snd_player_won");
    }
}
